package com.roadmap.ajax.handler;

import org.apache.log4j.Logger;

import com.roadmap.ajax.ProgressStatus;
import com.roadmap.client.module.IManager;
import com.roadmap.client.module.goal.GoalManager;
import com.roadmap.client.module.plan.IPlanProgress;
import com.roadmap.client.module.plan.PlanManager;
import com.roadmap.client.module.plan.PlanProgress;
import com.roadmap.client.module.task.ExecutionManager;
import com.roadmap.client.module.task.ITaskProgress;
import com.roadmap.client.module.task.TaskManager;
import com.roadmap.client.module.task.TaskProgress;
import com.roadmap.common.RdcLogger;
import com.roadmap.common.RdcResourceBundle;
import com.roadmap.entities.Execution;
import com.roadmap.entities.LifeGoal;
import com.roadmap.entities.LifePlan;
import com.roadmap.entities.LifeTask;

public class ExecHandler {
	private final static Logger logger = RdcLogger.getLogger(ExecHandler.class);
	private IManager execMgr;

	private IManager getExecMgr(String aspirantId, String taskId) {
		if (execMgr == null) {
			execMgr = new ExecutionManager(aspirantId, taskId);
		}
		return execMgr;
	}

	// create a new execution for the task. if successfully, return the latest
	// status of the task and relating plan， or else return NULL.
	public ProgressStatus createExec(String aspirantId, Execution exec) {
		try {
			ProgressStatus progress = new ProgressStatus();
			IManager mgr = getExecMgr(aspirantId, exec.getTaskId());
			if (mgr.getParent() instanceof LifeTask) {
				mgr.create(exec);

				// re-get the status and progress of the task
				IManager taskMgr = new TaskManager(aspirantId);
				LifeTask task = (LifeTask) taskMgr.get(exec.getTaskId());
				progress.setTaskId(task.getId());
				String tStatus = RdcResourceBundle.LIFETASK_STATUS_DESCRIPTIONS[task
						.getStatus()];
				progress.setTaskStatus(tStatus);
				ITaskProgress tp = new TaskProgress();
				progress.setTaskProgress(tp.getActualProgress(task));
				progress.setTaskSymptom(taskMgr.getEntityHealthy(task));

				// if the task belongs to a plan, return current result
				if (task.getGoalId() != null
						&& !task.getGoalId().trim().equalsIgnoreCase("")) {
					// re-get the status and progress of the plan
					IManager planMgr = new PlanManager(aspirantId);
					LifePlan plan = (LifePlan) planMgr.get(task.getGoalId());
					if (plan != null) {
						IPlanProgress pp = new PlanProgress();
						progress.setGoalId(plan.getId());
						progress.setGoalProgress(pp.getActualProgress(plan));

						IManager goalMgr = new GoalManager(aspirantId);
						LifeGoal goal = (LifeGoal) goalMgr
								.get(plan.getGoalId());
						planMgr.setParent(goal);
						String pStatus = RdcResourceBundle.LIFEGOAL_STATUS_DESCRIPTIONS[goal
								.getStatus()];
						progress.setGoalStatus(pStatus);
						progress.setGoalSymptom(planMgr.getEntityHealthy(plan));
					}
				}
			}

			return progress;
		}
		catch (Exception e) {
			logger.error(
					"failed to create the execution " + exec.getWhatItIs(), e);
		}

		return null;
	}

	public Execution saveExec(String aspirantId, Execution exec) {
		try {
			IManager mgr = getExecMgr(aspirantId, exec.getTaskId());
			if (exec.getId() == null) {
				mgr.create(exec);
			}
			else {
				mgr.edit(exec);
			}
			return exec;
		}
		catch (Exception e) {
			logger.error("failed to save the execution", e);
		}
		return null;
	}

	public boolean deleteExec(String aspirantId, Execution exec) {
		try {
			IManager mgr = getExecMgr(aspirantId, exec.getTaskId());
			exec = (Execution) mgr.get(exec.getId());
			if (exec != null) {
				mgr.delete(exec);
			}
			return true;
		}
		catch (Exception e) {
			logger.error("failed to save the execution", e);
		}
		return false;
	}
}
